package generic.net;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;

/**
 * Creates a stream that XMLEncoder can use to send/receive data using,
 * without having to close the stream. It does this by sending a small
 * 6-byte preamble containing a header and the size.
 *
 * @see SubInputStream
 * @author Adam Scarr <scarr.adam@gmail.com>
 */

public class SubOutputStream extends OutputStream {
    private OutputStream out;
    private Vector<Integer> buffer = new Vector<Integer>();

    /**
     * Creates a new SubOutputStream using out.
     * @param out The OutputStream to send the data over.
     */
    public SubOutputStream(OutputStream out) {
        this.out = out;
    }

    /**
     * Because we need to know the size of the substream for the header
     * we write all the bytes to a buffer before sending them.
     * @param b Bytes to write to buffer.

     */
    public void write(int b) {
        buffer.add(b);
    }

    /**
     * Close the subconnection, but not the parent connection. Now that we know
     * how much data will be sent, we can write the header and send the data.
     *
     * @throws java.io.IOException
     */
    public void close() throws IOException {
        byte[] header = new byte[6];
        // SUB Stream header
        header[0] = 's';
        header[1] = 'u';
        header[2] = 'b';
        header[3] = 's';

        // Two bytes representing the size of the stream, in big endian format.
        header[4] = (byte) (buffer.size() >> 8);
        header[5] = (byte) buffer.size();

        out.write(header);

        for (Integer b: buffer) {
            out.write(b);
        }
        out.flush();
    }
}
